package com.woniuxy.shiro;

import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * @Author: 马宇航
 * @Do: 写自定义域，其中会包含，认证Authentication 和授权Authorization 方法
 * @DateTime: 22/05/20/0020 下午 3:03
 * @Component: 成都蜗牛学苑
 **/
public class MyRealm extends AuthorizingRealm {
    /**
     * 授权的方法：认证成功后，封装出校长对象，授权方法中可以使用校长字段(就是账号用户名)，去数据库查询出其对应的角色和权限信息。
     *            接着，把角色集合和权限集合，封装进入SimpleAuthorizationInfo对象中，
     *            交给SecurityManager底层去进行foreach遍历比对subject是否有某个角色或者权限
     * ChangeLog : 1. 创建 (22/05/20/0020 下午 3:05 [马宇航]);
     * @param principals
     * @return org.apache.shiro.authz.AuthorizationInfo
    */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        //principals 这个参数，是下面的认证方法封装的SimpleAuthenticationInfo中的 校长
        System.out.println("校长："+principals);
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //正常的业务开发，这个信息是从哪里来的？数据库
        simpleAuthorizationInfo.addRole("admin");
        simpleAuthorizationInfo.addRole("root");
        simpleAuthorizationInfo.addStringPermission("manager:add");
        simpleAuthorizationInfo.addStringPermission("manager:edit");
        return simpleAuthorizationInfo;
    }
    /**
     * 认证的方法：根据subject.login，触发SecurityManager底层，调用认证方法。
     *          该认证方法，会使用username去查询数据库，把用户信息(账号密码)封装一个SimpleAuthenticationInfo中
     *          SimpleAuthenticationInfo将会return给SecurityManager用于登录认证比对凭证和密码是否一致，
     *          也会取出其中的校长传给授权方法，用于授权使用。
     * ChangeLog : 1. 创建 (22/05/20/0020 下午 3:05 [马宇航]);
     * @param token
     * @return org.apache.shiro.authc.AuthenticationInfo
    */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1.我们使用的是 UsernamePasswordToken 进行认证的
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        //2.获取用户名
        String username = usernamePasswordToken.getUsername();//subject.login(token)，从token中取出来的
        //3.去数据库中，找到该用户的所有信息。
        String password = "123456";//从数据库查询出来的
        //这个simp中的凭证参数，不允许直接使用 UsernamePasswordToken中的密码！
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(username+"校长",password,"myRealm");
        return simpleAuthenticationInfo;
    }
}
